package com.hsu.hsurpc.protocal;

import com.hsu.hsurpc.serializer.Serializer;
import com.hsu.hsurpc.serializer.SerializerFactory;
import io.vertx.core.buffer.Buffer;

import java.io.IOException;

/**
 * 协议消息编码器
 * 用于将 ProtocolMessage 对象编码为 Buffer
 * @Author Hsu琛君珩
 * @Date 2024-09-23 10:48
 * @Description
 * @Version: v1.0.0
 */
public class ProtocolMessageEncoder {

    /**
     * 编码消息，将 ProtocolMessage 对象转换为 Buffer
     *
     * @param protocolMessage 待编码的协议消息对象
     * @return 编码后的 Buffer
     * @throws IOException 当序列化出错时抛出
     */
    public static Buffer encode(ProtocolMessage<?> protocolMessage) throws IOException {
        if (protocolMessage == null || protocolMessage.getHeader() == null) {
            // 如果消息或消息头为空，返回空的 Buffer
            return Buffer.buffer();
        }
        ProtocolMessage.Header header = protocolMessage.getHeader();
        // 初始化缓冲区
        Buffer buffer = Buffer.buffer();
        // 写入消息头中各个字段
        buffer.appendByte(header.getMagic());       // 写入魔数
        buffer.appendByte(header.getVersion());     // 写入版本号
        buffer.appendByte(header.getSerializer());  // 写入序列化方式
        buffer.appendByte(header.getType());        // 写入消息类型
        buffer.appendByte(header.getStatus());      // 写入状态码
        buffer.appendLong(header.getRequestId());   // 写入请求 ID
        // 根据消息头中的序列化方式获取对应的序列化器
        ProtocolMessageSerializerEnum serializerEnum = ProtocolMessageSerializerEnum.getEnumByKey(header.getSerializer());
        if (serializerEnum == null) {
            throw new RuntimeException("不支持的序列化协议");
        }
        Serializer serializer = SerializerFactory.getInstance(serializerEnum.getValue());
        // 序列化消息体
        byte[] bodyBytes = serializer.serialize(protocolMessage.getBody());
        // 将消息体长度和消息体写入缓冲区
        buffer.appendInt(bodyBytes.length);
        buffer.appendBytes(bodyBytes);
        return buffer;
    }
}
